/*
 * This file is part of the <a href="http://code.google.com/p/pux">PUX Framework</a>
 *
 * Copyright 2008 by <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package de.teamskill.pux.engine;

import java.util.Enumeration;
import java.util.Hashtable;

/**
 * DataElement objects are wrappers around the "real" objects exchanged between
 * nodes. A DataObject may contain additional meta-data in terms of key-value
 * pairs, as attached to the annotations hash table.
 * 
 * @author <a href="mailto:jfendler@polytechnic.edu.na">Jens Fendler</a>
 * 
 */
public class DataElement {

	/**
	 * The object exchanged between the nodes
	 */
	private Object data;

	/**
	 * Key-Value Mappings. Non-String objects should provide custom toString()
	 * implementations as receiving nodes may assume a textual representation of
	 * the annotation values
	 */
	private Hashtable<String, Object> annotations;

	/**
	 * DataElement Constructor
	 * 
	 */
	public DataElement() {
		this(null, null);
	}

	/**
	 * DataElement Constructor
	 * 
	 * @param data
	 */
	public DataElement(Object data) {
		this(data, null);
	}

	/**
	 * DataElement Constructor
	 * 
	 * @param data
	 * @param annotations
	 */
	public DataElement(Object data, Hashtable<String, Object> annotations) {
		this.data = data;
		if (annotations == null) {
			this.annotations = new Hashtable<String, Object>();
		} else {
			this.annotations = annotations;
		}
	}

	/**
	 * annotate
	 * 
	 * @param key
	 * @param value
	 */
	public void annotate(String key, Object value) {
		annotations.put(key, value);
	}

	/**
	 * getAnnotation
	 * 
	 * @param key
	 * @return
	 */
	public Object getAnnotation(String key) {
		return annotations.get(key);
	}

	/**
	 * annotations
	 * 
	 * @return
	 */
	public Enumeration<Object> annotations() {
		return annotations.elements();
	}

	/**
	 * removeAnnotation
	 * 
	 * @param key
	 * @return
	 */
	public Object removeAnnotation(String key) {
		return annotations.remove(key);
	}

	/**
	 * equals
	 * 
	 * @param o
	 * @return
	 */
	public boolean equals(DataElement o) {
		return data == o.data || data.equals(o.data);
	}

	/**
	 * JavaBean-style getter-method for data
	 * 
	 * @return the data
	 */
	public Object getData() {
		return data;
	}

	/**
	 * /** JavaBean-style setter-method for data
	 * 
	 * @param data
	 *            the data to set
	 */
	public void setData(Object data) {
		this.data = data;
	}

	/**
	 * JavaBean-style getter-method for annotations
	 * 
	 * @return the annotations
	 */
	public Hashtable<String, Object> getAnnotations() {
		return annotations;
	}

	/**
	 * /** JavaBean-style setter-method for annotations
	 * 
	 * @param annotations
	 *            the annotations to set
	 */
	public void setAnnotations(Hashtable<String, Object> annotations) {
		this.annotations = annotations;
	}

}
